/*
 * @Author: ls
 * @Date: 2021-11-19 16:47:44
 * @LastEditTime: 2021-11-22 16:11:49
 * @LastEditors: ls
 * @Description: 节点事件
 * @FilePath: \BezierCurvePathCreater-master\assets\scripts\NodeEvents.js
 */

const { init } = require('./BezierData');

let NodeEvents = (function () {
	let _this = {};

	/**移动目标节点 */
	let moveTargetNode = null;
	/**是否点击 */
	let isMouseDown = null;
	/**是否操作 */
	let isOperate = true;

	/**
	 * 设置操作状态
	 * @param {*} bol
	 */
	_this.setOperateStatus = function (bol) {
		isOperate = bol;
	};

	/**point预制体 */
	let pointPrefab = null;
	/**control预制体 */
	let controlPrefab = null;
	/**父节点 */
	let pointParent = null;
	/**临时关键点 */
	let templists = [];

	/**点计数 */
	let PointNum = 0;

	_this.init = function (point, control, parent) {
		pointPrefab = point;
		controlPrefab = control;
		pointParent = parent;
	};

	_this.isFinish = function () {
		return templists == 0;
	};

	/**
	 * 创建新节点
	 * @param {*} ident 类型
	 * @param {*} pos 位置
	 * @param {*} isSelect 是否选中
	 * @returns
	 */
	let createPoint = function (ident, pos, isSelect = true) {
		let _name, node;

		if (ident == lcl.Ident.point) {
			_name = 'point';
			node = cc.instantiate(pointPrefab);
			node.ident = lcl.Ident.point;
		} else if (ident == lcl.Ident.control) {
			_name = 'control';
			node = cc.instantiate(controlPrefab);
			node.ident = lcl.Ident.control;
		}

		if (isSelect) moveTargetNode = node;

		let count = PointNum++;
		node.name = _name + '_' + count;
		node.parent = pointParent;
		node.setPosition(pos);
		lcl.NodeEvents.addDragEvents(node);
		lcl.NodeEvents.addDeleteEvents(node);

		// 创建编号
		let num = new cc.Node();
		num.parent = node;
		num.y = 20;
		num.addComponent(cc.Label).string = count;
		return node;
	};

	/**
	 * 添加触摸事件
	 * @param {*} canvas (canvas)
	 */
	_this.addTouchEvents = function (canvas = cc.find('Canvas')) {
		let target;
		// 鼠标按下
		canvas.on(cc.Node.EventType.MOUSE_DOWN, (event) => {
			// 鼠标左键
			if (event.getButton() == cc.Event.EventMouse.BUTTON_LEFT) {
				event.stopPropagation(); // 吞噬触摸
				target = event.target;

				// 创建坐标点,需要先把屏幕坐标转换到节点坐标下
				let mousePos = convertToNodeSpace(event);
				if (!atDrawingArea(mousePos)) return;
				if (!isOperate) lcl.Events.emit('hideDeleteBtn');

				if (lcl.BezierData.getBezierCurveType() == lcl.BezierCurveType.TwoBezier) {
					if (lcl.BezierData.isFirstCurve()) {
						if (templists.length === 0) {
							let start = createPoint(lcl.Ident.point, mousePos);
							templists.push(start);

							let control = createPoint(lcl.Ident.control, mousePos);
							templists.push(control);
						} else {
							let end = createPoint(lcl.Ident.point, mousePos);
							templists.push(end);

							lcl.BezierData.createTwoBezierCurve(templists); // 创建二阶贝塞尔曲线
							templists.length = 0;
						}
					} else {
						if (templists.length === 0) {
							let control = createPoint(lcl.Ident.control, mousePos);
							templists.push(control);
							let end = createPoint(lcl.Ident.point, mousePos);
							templists.push(end);
							lcl.BezierData.createTwoBezierCurve(templists); // 创建二阶贝塞尔曲线
							templists.length = 0;
						}
					}
				}

				if (lcl.BezierData.getBezierCurveType() == lcl.BezierCurveType.ThreeBezier) {
					if (lcl.BezierData.isFirstCurve()) {
						if (templists.length === 0) {
							let start = createPoint(lcl.Ident.point, mousePos);
							templists.push(start);

							let control1 = createPoint(lcl.Ident.control, mousePos);
							templists.push(control1);
						} else {
							let control2 = createPoint(lcl.Ident.control, mousePos);
							templists.push(control2);

							let end = createPoint(lcl.Ident.point, mousePos);
							templists.push(end);

							lcl.BezierData.createThreeBezierCurve(templists); // 创建三阶贝塞尔曲线
							templists.length = 0;
						}
					} else {
						if (templists.length === 0) {
							let control1 = createPoint(lcl.Ident.control, mousePos);
							templists.push(control1);

							let control2 = createPoint(lcl.Ident.control, mousePos);
							templists.push(control2);
						} else {
							let end = createPoint(lcl.Ident.point, mousePos);
							templists.push(end);

							lcl.BezierData.createThreeBezierCurve(templists); // 创建三阶贝塞尔曲线
							templists.length = 0;
						}
					}
				}

				isMouseDown = true;
			}
		});

		// 鼠标移动
		canvas.on(cc.Node.EventType.MOUSE_MOVE, (event) => {
			target = event.target;

			// 创建坐标点,需要先把屏幕坐标转换到节点坐标下
			let mousePos = convertToNodeSpace(event);
			lcl.Events.emit('setMouseLocation', mousePos);

			// 鼠标按下并且有指定目标节点
			if (isMouseDown && moveTargetNode && isDragMove(mousePos, moveTargetNode)) {
				moveTargetNode.setPosition(mousePos);
			}
		});

		// 鼠标抬起
		canvas.on(cc.Node.EventType.MOUSE_UP, (event) => {
			target = event.target;

			isMouseDown = false;
			moveTargetNode = null;
		});
	};

	/**
	 * 屏幕坐标转换到节点坐标
	 * @param {*} event
	 * @returns
	 */
	let convertToNodeSpace = function (event) {
		let canvas = cc.find('Canvas');
		return canvas.convertToNodeSpaceAR(event.getLocation());
	};

	/**
	 * 是否在绘制区域
	 * @param {*} pos
	 * @returns
	 */
	let atDrawingArea = function (pos) {
		let resolution = lcl.BezierData.getResolution();
		let halfW = resolution.width / 2;
		let halfH = resolution.height / 2;

		return pos.x > -halfW && pos.x < halfW && pos.y > -halfH && pos.y < halfH;
	};

	/**
	 * 是否能拖拽
	 * @param {*} mousePos
	 * @param {*} target
	 * @returns
	 */
	let isDragMove = function (mousePos, target) {
		let flag = false;
		switch (target.ident) {
			case lcl.Ident.point:
			case lcl.Ident.control:
				flag = atDrawingArea(mousePos);
				break;
			case lcl.Ident.window:
				flag = true;
		}
		return flag;
	};

	/**
	 * 是否能删除
	 * @param {*} node
	 * @returns
	 */
	let isDelete = function (node) {
		return node.ident == lcl.Ident.point;
	};

	/**
	 * 添加拖拽事件
	 * @param {*} node 绑定节点
	 * @param {*} target 拖拽目标节点
	 */
	_this.addDragEvents = function (node, target = node) {
		// 鼠标按下
		node.on(cc.Node.EventType.MOUSE_DOWN, (event) => {
			event.stopPropagation(); // 吞噬触摸
			// 鼠标左键
			if (event.getButton() == cc.Event.EventMouse.BUTTON_LEFT) {
				isMouseDown = true;
				moveTargetNode = target; // 选中可移动节点
			}
		});

		// 鼠标移动
		node.on(cc.Node.EventType.MOUSE_MOVE, (event) => {
			target.opacity = 100;
			cc.game.canvas.style.cursor = 'all-scroll'; // 设置光标移动
			// 鼠标按下并且有指定目标节点
			if (isMouseDown && moveTargetNode) {
				// 把屏幕坐标转换到节点坐标下
				let mousePos = convertToNodeSpace(event);
				if (isDragMove(mousePos, moveTargetNode)) moveTargetNode.setPosition(mousePos);
			}
		});

		// 鼠标离开
		node.on(cc.Node.EventType.MOUSE_LEAVE, (event) => {
			target.opacity = 255;
			cc.game.canvas.style.cursor = 'auto'; // 设置光标箭头
		});

		// 鼠标抬起
		node.on(cc.Node.EventType.MOUSE_UP, (event) => {
			isMouseDown = false;
			moveTargetNode = null; // 删除移动目标点
			lcl.BezierData.saveBezierPath(); //保存坐标点
		});
	};

	/**
	 * 添加删除事件
	 * @param {*} node
	 */
	_this.addDeleteEvents = function (node) {
		// 鼠标按下
		node.on(cc.Node.EventType.MOUSE_DOWN, (event) => {
			// 鼠标右键
			if (event.getButton() == cc.Event.EventMouse.BUTTON_RIGHT) {
				if (isDelete(event.target)) {
					let mousePos = convertToNodeSpace(event);

					lcl.BezierData.setDeleteTarget(event.target);
					lcl.Events.emit('showDeleteBtn', mousePos);
				}
				return;
			}
		});
	};

	return _this;
})();

module.exports = NodeEvents;
